import classNames from 'classnames';
import React from 'react';
import { Icon } from '../icon';

import { DropdownList, IOption, Options } from './DropdownList';

export interface IDropdownIndicatorProps {
  className?: string;
  disabled: boolean;
  opened: boolean;
}

const DropdownIndicator: React.SFC<IDropdownIndicatorProps> = (props: IDropdownIndicatorProps) => {
  const { opened } = props;
  const type = opened ? 'up' : 'down';
  return (
    <div className={props.className}>
      <Icon type={type} />
    </div>
  );
};

export interface IValueViewProps {
  value: IOption;
  onClose?: React.FocusEventHandler<Element>;
  onTagClose?: (value: IOption, index: number) => void;
  large?: boolean;
  small?: boolean;
}

const ValueView: React.SFC<IValueViewProps> = (props: IValueViewProps) => {
  return <span className="br-select__value-content">{props.value.label || ''}</span>;
};

export interface ISelectProps {
  options: Options;
  value: IOption;
  onChange?: (option: IOption) => void;
  emptyTips?: React.ReactNode;
  name?: string;
  type?: string;
  onFocus?: React.FocusEventHandler<Element>;
  className?: string;
  large?: boolean; // 36px
  small?: boolean; // 26px
  disabled?: boolean;
  style?: React.CSSProperties;
}
export interface ISelectState {
  drop: boolean;
  options: Options;
  filterOptions: Options;
  value: IOption;
}
export class Select extends React.Component<ISelectProps, ISelectState> {
  public static getDerivedStateFromProps(nextProps: ISelectProps, prevState: ISelectState) {
    if (nextProps.options !== prevState.options) {
      return {
        ...prevState,
        options: nextProps.options,
        filterOptions: nextProps.options,
      };
    }
    return null;
  }

  constructor(props: ISelectProps) {
    super(props);

    this.state = {
      drop: false,
      options: this.props.options,
      filterOptions: this.props.options,
      value: this.props.value,
    };

    this.handleClick = this.handleClick.bind(this);
    this.handleFilterChange = this.handleFilterChange.bind(this);
    this.handleInputClick = this.handleInputClick.bind(this);
    this.handleItemClick = this.handleItemClick.bind(this);
    this.closeAndResetOptions = this.closeAndResetOptions.bind(this);
  }

  public handleClick(e: any) {
    let dropFlag = !this.state.drop;
    if (dropFlag) {
      if (this.props.onFocus) {
        this.props.onFocus(e);
      }
    }
    this.setState({
      drop: dropFlag,
      filterOptions: this.props.options,
    });
  }

  public handleInputClick(e: React.MouseEvent<HTMLInputElement | HTMLDivElement>) {
    e.nativeEvent.stopImmediatePropagation();
  }

  public handleItemClick(option: IOption, index: number) {
    const beforeVal = this.props.value || this.state.value;
    if (this.props.onChange) {
      this.props.onChange(option);
    }
    this.setState({
      drop: !!option.disabled,
      filterOptions: this.props.options,
      value: option,
    });
  }

  public handleFilterChange(text: string) {
    let filterOptions = this.state.options;
    if (text && text.trim()) {
      filterOptions = this.state.options.filter((option) => {
        const label = option.label || option.value || '';
        return label.includes(text);
      });
    }
    this.setState(() => {
      return { filterOptions };
    });
  }

  public closeAndResetOptions() {
    this.setState({
      drop: false,
      filterOptions: this.props.options,
    });
  }

  public componentDidUpdate(prevProps: ISelectProps, prevState: ISelectState) {
    if (this.state.drop && !prevState.drop) {
      document.addEventListener('click', this.closeAndResetOptions);
    } else if (!this.state.drop && prevState.drop) {
      document.removeEventListener('click', this.closeAndResetOptions);
    }
  }

  public componentWillUnmount() {
    document.removeEventListener('click', this.closeAndResetOptions);
  }

  public render() {
    let list = null;
    // const value = this.props.value || this.state.value || (this.props.isMulti ? [] : { label: '', value: '' });
    const value = this.props.value || this.state.value || { label: '', value: '' };
    const values = value instanceof Array ? value : [value];
    if (this.state.drop) {
      list = <DropdownList
        options={this.state.filterOptions}
        onFilterChange={this.handleFilterChange}
        onInputClick={this.handleInputClick}
        onItemClick={this.handleItemClick}
        // value={values}
        value={values}
        emptyTips={this.props.emptyTips}
        type={this.props.type ? this.props.type : 'normal'}
      />;
    }

    // 是否为disabled状态
    const disabled = this.props.disabled || false;

    const modifierClassName = {
      'br-select--large': this.props.large,
      'br-select--small': this.props.small,
      'br-select--disabled': disabled,
    };
    return (
      <div
        className={classNames('br-select', modifierClassName, this.props.className)}
        style={this.props.style}
      >
        {/* <input type="hidden" name={this.props.name || ''} value={value.value || ''} /> */}
        <div className="br-select__controller" onClick={this.handleClick}>
          <span className="br-select__value">
            <ValueView
              large={this.props.large}
              small={this.props.small}
              value={value}
            // onTagClose={this.handleTagClose}
            />
          </span>

          <DropdownIndicator
            className="br-select__indicator"
            disabled={disabled}
            opened={this.state.drop}
          />
        </div>
        {list}
      </div>
    );
  }
}
